#include "mat_animation.h"
#include "mat_sfx.h"
#include "mat_sfx_manager.h"
#include "mat_game.h"

#include "ui/ui_sprite.h"
#include "num/rand.h"

MATAnimation::MATAnimation() : m_pFinishEventReceiveable(NULL),
					 m_pGemType(NULL)
{
	m_pGemType = new MATGem();
}

MATAnimation::~MATAnimation()
{
	UTIL_SAFE_DELETE(m_pGemType);
}

void		MATAnimation::Init(int y, int x, MATGem* pGemType)
{
	m_X = x;
	m_Y = y;

	pGemType->Copy(m_pGemType);
	
	m_IsFinish = false;
	m_pFinishEventReceiveable = NULL;
	
}


void		MATAnimation::Tick(float dt)
{
	if(m_IsFinish && m_pFinishEventReceiveable)
	{
		m_pFinishEventReceiveable->OnAnimationFinish(m_Type);
		m_pFinishEventReceiveable = NULL;
	}
}

void		MATAnimation::ForceFinish()
{ 
	m_IsFinish = true; 

	//if(m_pFinishEventReceiveable)
	//	m_pFinishEventReceiveable->OnAnimationFinish(m_Type);
	
	m_pFinishEventReceiveable = NULL;
}


// ---- SMALL TO BIG ----------------------

MATAniSmallTobig::MATAniSmallTobig() : MATAnimation(),
										m_ToMakeLogicallyBig(false)
{
	m_Type = ANI_TYPE_SMALLTOBIG;
	m_Scale = 0.5f;

}

void	MATAniSmallTobig::Tick(float dt)
{
	if(m_IsFinish)
		return;

	m_Scale += ( dt);
	if(m_Scale >= 1.0f)
	{
		m_Scale = 1.0f;
		m_IsFinish = true;

		if(m_ToMakeLogicallyBig)
		{
			MATGem* pGem = MATLogicBoard::Instance().GetContentAt(m_Y,m_X);
			if(pGem)
			{
				pGem->m_IsSmall = false;
				MATLogicBoard::Instance().SetContentAt(m_Y,m_X,pGem);
			}
		}
	}

	MATAnimation::Tick(dt);
}

void		MATAniSmallTobig::Init(int y, int x, MATGem* pGemType)
{
	m_ToMakeLogicallyBig = false;
	MATAnimation::Init(y, x, pGemType);
	m_Scale = 0.5f;
}

void		MATAniSmallTobig::GetInfos(math::Vec2& Pos, math::Vec2& Size,COLOR& c, float& Rotation)
{
	Size *= m_Scale;	
}

void	MATAniSmallTobig
::SetToMakeLogicallyBig(bool b) 
{
	m_pGemType->m_IsSmall = false;
	m_ToMakeLogicallyBig = b; 
}

//------- SMALL TO BIG ----------------------


//-------  Matched ---------------------

MATAniMatched::MATAniMatched() :    MATAnimation(),
									m_AlphaPercent(0.0f)
{
	m_Type = ANI_TYPE_MATCHED;	

}

void	MATAniMatched::Init(int y, int x, MATGem* pGemType)
{
	pGemType->m_IsGlow = true;
	MATAnimation::Init(y,x,pGemType);

	m_AlphaPercent = 0;
	
}
	
void	MATAniMatched::Tick(float dt)
{
	if(m_IsFinish)
		return;

    m_AlphaPercent += ( dt * 3.0f);	
	if(m_AlphaPercent >= 1.0f)
	{
		m_AlphaPercent = 1.0f;
		m_IsFinish = true;

		//MATGemCollect::Instance().Add(m

	}

	MATAnimation::Tick(dt);
}
	
void	MATAniMatched::GetInfos(math::Vec2& Pos, math::Vec2& Size,COLOR& c, float& Rotation)
{
	c = ColorfRGBA(1.0f, 1.0f, 1.0f, 1.0f);	
}


//------- Matched ---------------------

//-------  Moving ---------------------

MATAniMoving::MATAniMoving() :		MATAnimation(),
									m_MoveIndex(0),
									m_ToRotate(false),
									m_RotateDir(false),
									m_Rotation(0),
									m_ShouldAccelerate(false),
									m_Acceleration(1.0f)
{
	m_Type = ANI_TYPE_MOVING;	

}

void	MATAniMoving::Init(int y, int x, MATGem* pGemType)
{
	MATAnimation::Init(y,x,pGemType);
	m_MoveIndex = 0;
	m_ToRotate = false;
	m_Rotation = 0;
	m_ShouldAccelerate = false;
	m_Acceleration = 1.0f;
	//MATSFXManager::Instance().Spawn(MATSfx::SFX_MOVE,MATGame::GetBoardPos(y,x),
	//												1.0f,0,false,MATSounds::SFX_NONE);
	
}
	
void	MATAniMoving::Tick(float dt)
{
	if(m_IsFinish)
		return;

	float Dist = 0;
	
	if(m_ShouldAccelerate)
	{
		m_Acceleration += ( dt * 2.0f);
		if(m_Acceleration > 3.0f)
			m_Acceleration = 3.0f;

		Dist = dt * m_Acceleration;
	}
	else
	{
		Dist = dt;
	}

	m_Pos += (m_Dir * Dist);
	math::Vec2 NewDir = m_PosTarget - m_Pos;
	NewDir.Normalize();

	bool Reach = false;
	if(NewDir.x > 0 && m_Dir.x <= 0)
		Reach = true;

	else if(NewDir.x < 0 && m_Dir.x >= 0)
		Reach = true;

	else if(NewDir.y > 0 && m_Dir.y <= 0)
		Reach = true;

	else if(NewDir.y < 0 && m_Dir.y >= 0)
		Reach = true;

	
	if(Reach)
	{
		m_MoveIndex++;
		if(m_MoveIndex >= (int)m_MovePositions.size())
		{
			m_IsFinish = true;			
		}
		else
		{
			m_PosTarget = m_MovePositions[m_MoveIndex];
			m_Dir = m_PosTarget - m_Pos;
			m_Dir.Normalize();

			
		}
	}
	

	if(m_ToRotate)
	{
		  m_Rotation += 180 * dt * m_RotateDir;
	}
	else
	{
		MATSFXManager::Instance().Spawn(MATSfx::SFX_MOVE, 
											m_Pos,
											1.0f,0,false,MATSounds::SFX_NONE);
	}

	MATAnimation::Tick(dt);

	
}

void	MATAniMoving::GetInfos(math::Vec2& Pos, math::Vec2& Size,COLOR& c, float& Rotation)
{
	Pos = m_Pos;
	Rotation = m_Rotation;
}

void	MATAniMoving::AddMovePosition(const math::Vec2& Pos)
{
	m_MovePositions.push_back(Pos);
	int Count = (int)m_MovePositions.size();

	// initialize with first two
	if(m_MoveIndex < 1 && Count == 2)
	{
		m_MoveIndex = 1;
		m_Dir = m_MovePositions[1] - m_MovePositions[0];
		m_Dir.Normalize();
		m_Pos = m_MovePositions[0];
		m_PosTarget = m_MovePositions[1];
	}
}

void	MATAniMoving::ClearPositions() 
{ 
	m_MovePositions.resize(0); 
	m_MoveIndex = -1;
}

void	MATAniMoving::ToRotate(bool b) 
{ 
	m_ToRotate = b;
	if(b)
	{
		m_RotateDir = 1;
		if( num::RAND32::Instance().RandInt(0,1) == 1)
			m_RotateDir = -1;
	}
}

//-------  Moving ---------------------
